package com.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.reggie.common.BaseContext;
import com.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j

//检查 用户是否已经完成登录
//拦截器    过滤器
//   /* 表示所有的路径 都拦截
@WebFilter(filterName = "logi-nCheckFilter", urlPatterns = "/*")
@ServletComponentScan
public class LoginCheckFilter implements Filter {
    //是一个工具类  用于路径匹配器 支持通配符写法
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    @Override
//    dofilter(客户端发送的请求，我们的回应，用于放行该方法)
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;//请求
        HttpServletResponse response = (HttpServletResponse) servletResponse;//回应
//        {}是占位符  类似c
//       getRequestURI() 返回客户端发出请求除去host（域名或者ip）部分的路径
//       request.getRequestURL() 返回客户端发出请求时的完整URL，如：http://localhost:8080/test/test.jsp
        log.info("拦截到的请求:{}", request.getRequestURI());
//        filterChain.doFilter(request, response);

//        1、获取本次请求的URI
//        2、判断本次请求是否需要处理
//        3、如果不需要处理，直接放行
//        4、判断登录状态，如果已登录，放行
//        5、如果未登录则返回未登录结果

//        1、获取本次请求的URI
        String requestURI = request.getRequestURI();
        log.info("拦截到的{}", requestURI);
        //        2、判断本次请求是否需要处理

//       2、 不需要处理的页面路径
        String[] urls = new String[]{ //java字符串对象写法
                "/employee/login",
                "/employee/logout",
                "/backend/**",//通配符
                "/front/**",//front是移动端的
//                , "/employee/page"
//                手机端
                "/user/sendMsg",
                "/user/login"

        };
//        调用匹配器
        boolean check = check(urls, requestURI);
//匹配器

//        3、如果不需要处理，直接放行
        if (check) {
            log.info("本次拦截不需要处理{}", requestURI);
            filterChain.doFilter(request, response); //放
            return;
        }
//        4、判断登录状态，如果已登录，放行
        if (request.getSession().getAttribute("user") != null) {
            log.info("用户已登录 id:{}",request.getSession().getAttribute("user"));
//              在这里添加 线程 来保存 用户的id
//              获取当前登录用户的id
                    Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);

            filterChain.doFilter(request, response);
            return;
        }
        //        4.2、判断登录状态，如果已登录，放行
        if (request.getSession().getAttribute("employee") != null) {
            log.info("用户已登录 id:{}",request.getSession().getAttribute("employee"));
//              在这里添加 线程 来保存 用户的id
//              获取当前登录用户的id
            Long empId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(empId);

            filterChain.doFilter(request, response);
            return;
        }
//        5、如果未登录则返回未登录结果
//                    先看一下 js代码如何判断
//        这个是输出流方法 把数据结果输出给前端 又因为我们把结果都封装为JESON R方法
        log.info("用户未登录");
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
    }

    //    路径匹配器
    public boolean check(String[] urls, String requestURI) {
//        循环不需要拦截的页面 与 用户发起请求的路径 进行匹配
        for (String url : urls) {
//            PATH_MATCHER 匹配器对象
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) {
                return true;
            }
        }
        return false;
    }

}
